package de.recipeminer.persistence;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.apache.log4j.Logger;

import java.util.concurrent.ExecutionException;

/**
 * @autor: Markus Ackermann
 */
public class Db4oCompanionFactory {
    private static Logger logger = Logger.getLogger(Db4oCompanionFactory.class);
    private static Db4oCompanionFactory instance = null;
    LoadingCache<Db4oCompanionProvider, Db4oObjectCompanion> companionCache;

    private Db4oCompanionFactory() {
        initCache();
    }

    public static Db4oCompanionFactory getInstance() {
        if(instance == null) {
            instance = new Db4oCompanionFactory();
        }
        return instance;
    }

    public Db4oObjectCompanion companionFor(Db4oCompanionProvider object) {
        try {
            return companionCache.get(object);
        } catch (ExecutionException e) {
            logger.error("Error retrieving compation for: " + object,e);
            return null;
        }
    }

    public void invalidateCache() {
        companionCache.invalidateAll();
    }

    private void initCache() {
        companionCache = CacheBuilder.newBuilder()
            .maximumSize(500)
            .concurrencyLevel(1)
            .build(
                    new CacheLoader<Db4oCompanionProvider, Db4oObjectCompanion>() {
                        @Override
                        public Db4oObjectCompanion load(Db4oCompanionProvider object) throws Exception {
                            return createCompanion(object);
                        }
                    });
    }

    private Db4oObjectCompanion createCompanion(Db4oCompanionProvider object) {
        return new Db4oObjectCompanion(object, Db4oHelpers.currentDatabase());
    }
}
